package org.jeecg.modules.iot.mqtt.server.service.processor.socketOperate;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.jeecg.common.api.vo.Result;
import org.jeecg.modules.iot.model.SocketPort;
import org.jeecg.modules.iot.model.UniqueSerialNumberGenerator;
import org.jeecg.modules.iot.model.socket.*;
import org.jeecg.modules.iot.mqtt.server.MqttSendClient;
import org.jeecg.modules.iot.service.ISocketService;
import org.jeecg.modules.iot.service.impl.LocationServiceImpl;
import org.jeecg.modules.rental.api.IRentalEBikeAPI;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

@Component
public class ChargePileProcessor {

    @Autowired
    private MqttSendClient mqttSendClient;

    @Autowired
    private ISocketService socketService;
    @Autowired
    private LocationServiceImpl locationService;
   /* @Autowired
    private SseEmitterManager sseEmitterManager;*/
   /* @Autowired
    private RentalSocketDeviceMapper rentalSocketDeviceMapper;

    @Autowired
    private RentalPayAccountMapper rentalPayAccountMapper;

    @Autowired
    private RentalCarMapper rentalCarMapper;

    @Autowired
    private IRentalChargingRecordService iRentalChargingRecordService;

    @Autowired
    private RentalChargingRecordMapper rentalChargingRecordMapper;
    @Autowired
    private IRentalAccountPackageService   rentalAccountPackageService;*/

    @Autowired
    private IRentalEBikeAPI iRentalCarAPI;

    private final ObjectMapper objectMapper = new ObjectMapper();

    public Result openPort(String deviceCode, int port, int time, int power, int autoOpen, String openId) {
        Integer seq = Integer.parseInt(UniqueSerialNumberGenerator.getNextSequence());
        try {
            LocalDateTime now=LocalDateTime.now();
            // 查询车辆的有效订单，增加 openId 查询条件
//            LambdaQueryWrapper<RentalAccountPackage> packageQuery = new LambdaQueryWrapper<>();
//            packageQuery.eq(RentalAccountPackage::getAccountId, openId); // 增加 openId 查询条件
//            packageQuery.and(wrapper -> wrapper.isNull(RentalAccountPackage::getReturnTime)
//                    .or()
//                    .ne(RentalAccountPackage::getDepositStatus, 1));
            /*List<RentalAccountPackage> rentalAccountPackages = rentalAccountPackageService.list(packageQuery);
            if (rentalAccountPackages == null || rentalAccountPackages.isEmpty()) {
                System.out.println("验证失败：没找到在租车辆");
                return Result.error("您没有在租车辆,无法免费充电");
            }*/
           /* SocketPort socketPort=new SocketPort();
            RentalChargingRecord record=new RentalChargingRecord();
            socketPort=socketService.queryByDeviceCode(port,deviceCode);*/
           /* if(socketPort!=null){
              record.setStartEnergy( socketPort.getEnergy());
            }else {
              record.setStartEnergy(0L);
            }
            record.setPortId(port);
            record.setAccountId(openId);
            record.setSocketDeviceId(deviceCode);
            record.setStartTime(now);
            record.setStuts(1);
            record.setStartEnergy(socketPort.getEnergy());
            record.setTime(time);
            record.setUserType(0);
            rentalChargingRecordMapper.insert(record);*/

            OpenPortData openPortData = new OpenPortData();
            openPortData.setDeviceCode(deviceCode);
            openPortData.setCmd(3); // 打开端口的命令码
            openPortData.setPort(port);
            openPortData.setTime(time);
            openPortData.setPower(power);
            openPortData.setAutoOpen(autoOpen);
            openPortData.setSeq(String.valueOf(seq));


            String jsonPayload = objectMapper.writeValueAsString(openPortData);
           // String topic = "/mqtt_server/" + deviceCode + "/user/get";
            // 发送消息到 MQTT
            String topic = "/mqtt_server/" + deviceCode + "/user/get";
            mqttSendClient.publishNormal(true, topic, jsonPayload);
            System.out.println("Open port command sent: " + jsonPayload);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.OK();
    }

    public Integer closePort(String deviceCode, int port) {
        Integer seq = Integer.parseInt(UniqueSerialNumberGenerator.getNextSequence());
        try {
            ClosePortData closePortData = new ClosePortData();
            closePortData.setDeviceCode(deviceCode);
            closePortData.setCmd(4); // 关闭端口的命令码
            closePortData.setPort(port);
            closePortData.setSeq(String.valueOf(seq));

            String jsonPayload = objectMapper.writeValueAsString(closePortData);

            // 发送消息到 MQTT
            String topic = "/mqtt_server/" + deviceCode + "/user/get";
            mqttSendClient.publishNormal(true, topic, jsonPayload);
            System.out.println("Close port command sent: " + jsonPayload);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return seq;
    }

    public Integer queryPort(String deviceCode) {
        Integer seq = Integer.parseInt(UniqueSerialNumberGenerator.getNextSequence());
        try {
            PortStatusData portStatusData = new PortStatusData();
            portStatusData.setDeviceCode(deviceCode);
            portStatusData.setCmd(4); // 关闭端口的命令码
            portStatusData.setSeq(String.valueOf(seq));

            String jsonPayload = objectMapper.writeValueAsString(portStatusData);

            // 发送消息到 MQTT
            String topic = "/mqtt_server/" + deviceCode + "/user/get";
            mqttSendClient.publishNormal(true, topic, jsonPayload);
            System.out.println("Close port command sent: " + jsonPayload);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return seq;
    }

    public void handleCloseAndOpen(CloseAndOpenResponse data) {
        // 处理设备登录逻辑
        if (data.getCmd()==3){
            System.out.println("打开指定端口输出成功: " + data);
        }else if (data.getCmd()==4){
            System.out.println("关闭指定端口输出成功: " + data);
        }


    }

    /*public void handleDeviceLogin(DeviceLoginData data) {
        // 处理设备登录逻辑
        System.out.println("处理设备登录逻辑: " + data);
        try {
            DeviceLoginResponse response = new DeviceLoginResponse();
            response.setDeviceCode(data.getDeviceCode());
            response.setCmd(data.getCmd());
            response.setServerType(data.getServerType());
            response.setAddress(data.getAddress());
            response.setPort(data.getPort());
            response.setMqttUser(data.getMqttUser());
            response.setMqttPass(data.getMqttPass());
            response.setHeart(data.getHeart());
            response.setRevise(0); // 示例值，具体值根据业务逻辑设置
            response.setSeq(data.getSeq());
            LambdaQueryWrapper<RentalSocketDevice> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(RentalSocketDevice::getDeviceCode, data.getDeviceCode());
            RentalSocketDevice existingDevice = rentalSocketDeviceMapper.selectOne(queryWrapper);


            if (existingDevice == null) {
                // 如果DeviceCode不存在，插入新记录
                RentalSocketDevice socket = new RentalSocketDevice();
                socket.setImei(data.getImei());
                socket.setDeviceCode(data.getDeviceCode());
                socket.setIccid(data.getIccid());
                socket.setPortNum(data.getAllData().size());
                socket.setVersion(data.getVersion());
                rentalSocketDeviceMapper.insert(socket);
            } else {
                System.out.println("DeviceCode已存在，不进行插入操作");
            }
            String responseJson = objectMapper.writeValueAsString(response);
            String topic = "/mqtt_server/" + data.getDeviceCode() + "/user/get";
            mqttSendClient.publishNormal(true, topic, responseJson);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }*/

    public void handleDeviceHeartbeat(DeviceHeartbeatData data) throws IOException {
        List<PortData> portDataList = data.getAllData();
        // 处理设备心跳逻辑
        if (portDataList != null && !portDataList.isEmpty()){
            for (int i = data.getAllData().size() - 1; i >= 0; i--) {
                PortData portData=  data.getAllData().get(i);
                SocketPort socket=new SocketPort();
                socket.setTs(new Timestamp(new Date().getTime()));
                socket.setEnergy(portData.getEnergy());
                socket.setOutTime(portData.getOutTime());
                socket.setPortId(portData.getPort());
                socket.setPower(portData.getPower());
                socket.setBtStat(portData.getBtStat());
                socket.setDeviceCode(data.getDeviceCode());

                SocketPort lastSoPort = socketService.queryByDeviceCode(socket.getPortId(), socket.getDeviceCode());

                if (lastSoPort != null) {
                    long durationMillis = socket.getTs().getTime() - lastSoPort.getTs().getTime();
                    double durationHours = durationMillis / (1000.0 * 60 * 60);

                    if (durationHours > 0) {
                        double energyDifference = portData.getEnergy() - lastSoPort.getEnergy();
                        Long averagePower = (long) (energyDifference / durationHours);
                        socket.setAveragePower(averagePower);
                    } else {
                        socket.setAveragePower(0l);
                    }
                } else {
                    socket.setAveragePower(0l);
                }
               /* if (socket.getBtStat()==0){
                    LambdaQueryWrapper<RentalChargingRecord> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(RentalChargingRecord::getSocketDeviceId, data.getDeviceCode());
                    queryWrapper.eq(RentalChargingRecord::getPortId, socket.getPortId());
                    queryWrapper.isNull(RentalChargingRecord::getEndTime);
                    List<RentalChargingRecord> recordList = rentalChargingRecordMapper.selectList(queryWrapper);
                    for (int i1 = recordList.size() - 1; i1 >= 0; i1--) {
                        RentalChargingRecord record= recordList.get(i1);
                        record.setEndTime(LocalDateTime.now());
                        rentalChargingRecordMapper.updateById(record);
                        RentalPayAccount account=rentalPayAccountMapper.selectById(record.getAccountId());

                    }
                }else {
                    LambdaQueryWrapper<RentalChargingRecord> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(RentalChargingRecord::getSocketDeviceId, data.getDeviceCode());
                    queryWrapper.eq(RentalChargingRecord::getPortId, socket.getPortId());
                    queryWrapper.isNull(RentalChargingRecord::getEndTime);
                    List<RentalChargingRecord> recordList = rentalChargingRecordMapper.selectList(queryWrapper);
                    for (int i1 = recordList.size() - 1; i1 >= 0; i1--) {

                        RentalChargingRecord record= recordList.get(i1);
                        RentalPayAccount account=rentalPayAccountMapper.selectById(record.getAccountId());

                        LambdaQueryWrapper<RentalAccountPackage> packageQuery = new LambdaQueryWrapper<>();
                        packageQuery.eq(RentalAccountPackage::getAccountId, account.getAccountId());
                        packageQuery.and(wrapper -> wrapper.isNull(RentalAccountPackage::getReturnTime)
                                .or()
                                .ne(RentalAccountPackage::getDepositStatus, 1));
                        List<RentalAccountPackage> rentalAccountPackages = rentalAccountPackageService.list(packageQuery);
                        for (int i2 = rentalAccountPackages.size() - 1; i2 >= 0; i2--) {
                            RentalAccountPackage accountPackage=rentalAccountPackages.get(i2);
                            String  portJson= JsonUtil.createPubJson(BussinesType.SOCKET.getCode(),true,socket);
                            RentalCar car=rentalCarMapper.selectById(accountPackage.getCarId());
                            //sseEmitterManager.sendMessageToEmitter(car.getCarCode(), BussinesType.ALLINFO.getType(), portJson);
                        }


                    }
                }
                String socketPortJson= JsonUtil.createPubSocket(socket);
                //sseEmitterManager.sendSocketMessageToEmitter(data.getDeviceCode(), BussinesType.SOCKET.getType(), socketPortJson,socket.getPortId());
                //查看对应订单的插座信息。
*/


                socketService.add(socket);


            }
        }

        System.out.println("处理设备心跳逻辑: " + data);
    }

    public void handleDeviceReport(DeviceReportData data) {
        // 处理设备上报逻辑
        System.out.println("处理设备上报逻辑: " + data);
        try {
            DeviceReportResponse response = new DeviceReportResponse();
            List<PortData> portDataList = data.getAllData();
            if (portDataList != null && !portDataList.isEmpty()){
                for (int i = data.getAllData().size() - 1; i >= 0; i--) {
                    PortData portData=  data.getAllData().get(i);
                    SocketPort socket=new SocketPort();
                    socket.setTs(new Timestamp(new Date().getTime()));
                    socket.setEnergy(portData.getEnergy());
                    socket.setOutTime(portData.getOutTime());
                    socket.setPortId(portData.getPort());
                    socket.setPower(portData.getPower());
                    socket.setBtStat(portData.getBtStat());
                    socket.setDeviceCode(data.getDeviceCode());


                    SocketPort lastSoPort = socketService.queryByDeviceCode(socket.getPortId(), socket.getDeviceCode());

                    if (lastSoPort != null) {
                        long durationMillis = socket.getTs().getTime() - lastSoPort.getTs().getTime();
                        double durationHours = durationMillis / (1000.0 * 60 * 60);

                        if (durationHours > 0) {
                            double energyDifference = portData.getEnergy() - lastSoPort.getEnergy();
                            Long averagePower = (long) (energyDifference / durationHours);
                            socket.setAveragePower(averagePower);
                        } else {
                            socket.setAveragePower(0l);
                        }
                    } else {
                        socket.setAveragePower(0l);
                    }
                    socketService.add(socket);

                }
            }

            response.setDeviceCode(data.getDeviceCode());
            response.setCmd(data.getCmd());
            response.setSeq(data.getSeq());

            String responseJson = objectMapper.writeValueAsString(response);
            String topic = "/mqtt_server/" + data.getDeviceCode() + "/user/get";
            mqttSendClient.publishNormal(true, topic, responseJson);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    private void handleOtherCMD(OtherCMDData data) {
        // 处理其他 CMD 逻辑
        System.out.println("处理其他 CMD 逻辑: " + data);
        try {
            OtherCMDResponse response = new OtherCMDResponse();
            response.setDeviceCode(data.getDeviceCode());
            response.setCmd(data.getCmd());
            response.setPort(data.getPort());
            response.setSeq(data.getSeq());
            response.setAllData(data.getAllData()); // 根据业务逻辑设置 ALLDATA

            String responseJson = objectMapper.writeValueAsString(response);
            String topic = "/mqtt_server/" + data.getDeviceCode() + "/user/get";
            mqttSendClient.publishNormal(true, topic, responseJson);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    private String extractJsonData(String payload) {
        // 这里实现提取JSON数据的逻辑
        return payload;
    }


    public Result openManagePort(String deviceCode, int port, int time, int power, int autoOpen) {
        try {
        LocalDateTime now=LocalDateTime.now();
        Integer seq = Integer.parseInt(UniqueSerialNumberGenerator.getNextSequence());
        SocketPort socketPort=new SocketPort();
//        RentalChargingRecord record=new RentalChargingRecord();
        socketPort=socketService.queryByDeviceCode(port,deviceCode);
//        LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//        if (DataScopeEnums.DATA_SCOPE_MANAGE.getValue().equals(loginUser.getRoleDataScope())){
//            if(socketPort!=null){
//                record.setStartEnergy( socketPort.getEnergy());
//            }else {
//                record.setStartEnergy(0L);
//            }
            /*record.setPortId(port);
            record.setAccountId(loginUser.getId());
            record.setSocketDeviceId(deviceCode);
            record.setStartTime(now);
            record.setStuts(1);
            record.setStartEnergy(socketPort.getEnergy());
            record.setTime(time);
            record.setUserType(1);
            rentalChargingRecordMapper.insert(record);*/

            OpenPortData openPortData = new OpenPortData();
            openPortData.setDeviceCode(deviceCode);
            openPortData.setCmd(3); // 打开端口的命令码
            openPortData.setPort(port);
            openPortData.setTime(time);
            openPortData.setPower(power);
            openPortData.setAutoOpen(autoOpen);
            openPortData.setSeq(String.valueOf(seq));

            String jsonPayload  = objectMapper.writeValueAsString(openPortData);

            // String topic = "/mqtt_server/" + deviceCode + "/user/get";
            // 发送消息到 MQTT
            String topic = "/mqtt_server/" + deviceCode + "/user/get";
            mqttSendClient.publishNormal(true, topic, jsonPayload);
            return Result.OK();

//        }else {
//            return Result.error("暂无权限");
//        }

        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public Result closeManagePort(String deviceCode, int port) {
        Integer seq = Integer.parseInt(UniqueSerialNumberGenerator.getNextSequence());
        try {

//            LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
//            if (DataScopeEnums.DATA_SCOPE_MANAGE.getValue().equals(loginUser.getRoleDataScope())){
            ClosePortData closePortData = new ClosePortData();
            closePortData.setDeviceCode(deviceCode);
            closePortData.setCmd(4); // 关闭端口的命令码
            closePortData.setPort(port);
            closePortData.setSeq(String.valueOf(seq));

            String jsonPayload = objectMapper.writeValueAsString(closePortData);

            // 发送消息到 MQTT
            String topic = "/mqtt_server/" + deviceCode + "/user/get";
            mqttSendClient.publishNormal(true, topic, jsonPayload);

//            }else {
//                return Result.error("暂无权限");
//            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Result.ok();
    }
}